package com.patterns.vistor;

/**
 * 访问者模式
 * 访问的是结构固定的，例如电脑的结构是定死的，如果结构是变化的，访问者模式不适用
 * 场景：根据不同的人组装电脑给出不同的折扣
 * @author fwj
 * @date 2021/4/22 14:40
 **/
public class Computer {
    ComputerPart cpu = new CPU();
    ComputerPart memory = new Memory();
    ComputerPart board = new Board();

    public void accept(Visitor visitor) {
        this.cpu.accept(visitor);
        this.memory.accept(visitor);
        this.board.accept(visitor);
    }

    public static void main(String[] args) {
        PersonalVisitor personalVisitor = new PersonalVisitor();
        new Computer().accept(personalVisitor);
        System.out.println(personalVisitor.totalPrice);
    }

}

interface ComputerPart {
    void accept(Visitor visitor);

    double getPrice();
}

class CPU implements ComputerPart {
    @Override
    public void accept(Visitor visitor) {
        visitor.visitorCpu(this);
    }

    @Override
    public double getPrice() {
        return 500;
    }
}

class Memory implements ComputerPart {
    @Override
    public void accept(Visitor visitor) {
        visitor.visitorMemory(this);
    }

    @Override
    public double getPrice() {
        return 200;
    }
}

class Board implements ComputerPart {
    @Override
    public void accept(Visitor visitor) {
        visitor.visitorBoard(this);
    }

    @Override
    public double getPrice() {
        return 600;
    }
}

interface Visitor {
    void visitorCpu(CPU cpu);

    void visitorMemory(Memory memory);

    void visitorBoard(Board board);
}

class PersonalVisitor implements Visitor {
    double totalPrice = 0.0;

    @Override
    public void visitorCpu(CPU cpu) {
        totalPrice += cpu.getPrice() * 0.95;
    }

    @Override
    public void visitorMemory(Memory memory) {
        totalPrice += memory.getPrice() * 0.95;
    }

    @Override
    public void visitorBoard(Board board) {
        totalPrice += board.getPrice() * 0.95;
    }
}

class CorpVisitor implements Visitor {
    double totalPrice = 0.0;

    @Override
    public void visitorCpu(CPU cpu) {
        totalPrice += cpu.getPrice() * 0.9;
    }

    @Override
    public void visitorMemory(Memory memory) {
        totalPrice += memory.getPrice() * 0.9;
    }

    @Override
    public void visitorBoard(Board board) {
        totalPrice += board.getPrice() * 0.9;
    }
}

class StudentVisitor implements Visitor {
    double totalPrice = 0.0;

    @Override
    public void visitorCpu(CPU cpu) {
        totalPrice += cpu.getPrice() * 0.85;
    }

    @Override
    public void visitorMemory(Memory memory) {
        totalPrice += memory.getPrice() * 0.85;
    }

    @Override
    public void visitorBoard(Board board) {
        totalPrice += board.getPrice() * 0.85;
    }
}